package utils

import (
	"crypto/rand"
	"errors"
	"fmt"
	"net"
	"strconv"
	"strings"
)

/** 随机生成一个MAC地址 */
func CreateMACAddress() net.HardwareAddr {
	/**
	MAC格式： | I/G | G/L | OUI |  厂商分配(24位) |
	I/G = 0 表示单播
	I/G = 1 表示多播
	G/L = 0 表示全球地址
	G/L = 1 表示局域地址
	参考：https://www.cnblogs.com/lsgxeva/p/13932262.html
	*/
	hw := make(net.HardwareAddr, 6)
	hw[0] = 0x00
	hw[1] = 0x00
	rand.Read(hw[2:])
	return hw
}

/** IP地址转Int */
func IPAdrrToInt(ip string) (int, error) {
	strs := strings.Split(ip, ".")
	if len(strs) != 4 {
		return 0, errors.New("错误的IPV4地址格式")
	}
	a, err1 := strconv.Atoi(strs[0])
	b, err2 := strconv.Atoi(strs[1])
	c, err3 := strconv.Atoi(strs[2])
	d, err4 := strconv.Atoi(strs[3])
	if err1 != nil || err2 != nil || err3 != nil || err4 != nil {
		return 0, errors.New("错误的IPV4地址格式")
	}
	return ((a << 24) | (b << 16) | (c << 8) | d), nil
}

/** Int转IP地址 */
func IntToIPAddr(ip int) string {
	a := (ip >> 24) & 0xFF
	b := (ip >> 16) & 0xFF
	c := (ip >> 8) & 0xFF
	d := (ip >> 0) & 0xFF
	return fmt.Sprintf("%d.%d.%d.%d", a, b, c, d)
}

/** 解析CIDR块， 返回网络地址和mask, mask 以高位为1的形式表示 */
func IPCIDRParse(cidr string) (int, int) {
	strs := strings.Split(cidr, "/")
	net, _ := IPAdrrToInt(strs[0])
	maskLen, _ := strconv.Atoi(strs[1])
	maskBits := 0
	for i := 0; i < maskLen; i++ {
		maskBits |= (1 << (31 - i))
	}
	netMasked := maskBits & net
	return netMasked, maskBits
}

/** 把解析后的CIDR块重新解析 */
func IPCIDREncode(ip int, mask int) string {
	count := 0
	for i := 0; i < 32; i++ {
		if ((mask >> (31 - i)) & 1) == 1 {
			count++
		} else {
			break
		}
	}
	return IntToIPAddr(ip) + "/" + strconv.Itoa(count)
}
